﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Collections.Specialized;
using System.Linq;
using System.Web;
using System.Web.SessionState;
using System.Net;
using System.Net.Cache;
using System.IO;
using System.IO.Compression;
using System.Text;
using XQ.Framework.html;
using System.Security;
using System.Text.RegularExpressions;
using System.Diagnostics;
using XQ.Framework.core;
using XQ.Framework.io;

namespace XQ.Framework.http
{
    /// <summary>
    ///StealDataFromWeb 的摘要说明
    /// </summary>
    public class HttpHelper : IRequiresSessionState
    {
        public class Cookie
        {
            /// <summary>
            /// 删除cookie
            /// </summary>
            /// <param name="context"></param>
            /// <param name="names"></param>
            public static void RemoveCookie(HttpContext context, params string[] names)
            {
                if (!ValidateHelper.IsPlumpArray<string>(names)) { return; }
                names.ToList().ForEach(delegate(string name)
                {
                    HttpCookie cookie = context.Request.Cookies[name];
                    if (cookie == null)
                    {
                        return;
                    }
                    cookie.Expires = DateTime.Now.AddDays(-1);
                    context.Response.Cookies.Add(cookie);
                    //remove方法只是不让服务器向客户机发送那个被删除的cookie，与此cookie留不留在客户机里无关。
                    //remove无法删除客户端的cookie，需要设置过期时间
                    //context.Response.Cookies.Remove("");
                });
            }
            /// <summary>
            /// 移出所有cookie
            /// </summary>
            /// <param name="context"></param>
            public static void RemoveAllCookies(HttpContext context)
            {
                for (int i = 0; i < context.Response.Cookies.Count; ++i)
                {
                    RemoveCookie(context, context.Response.Cookies[i].Name);
                }
            }

            public static string GetCookie(HttpContext context, string name)
            {
                HttpCookie cookie = context.Request.Cookies[name];
                if (cookie != null)
                {
                    return ConvertHelper.getString(cookie.Value);
                }
                return string.Empty;
            }

            public static string GetCookie(HttpContext context, string name, string key)
            {
                HttpCookie cookie = context.Request.Cookies[name];
                if (cookie != null && cookie.HasKeys)
                {
                    return ConvertHelper.getString(cookie[key]);
                }
                return string.Empty;
            }

            public static void SetCookie(HttpContext context, string name, string value, double expires = 60*24)
            {
                HttpCookie cookie = context.Request.Cookies[name];
                if (cookie == null)
                {
                    cookie = new HttpCookie(name);
                }
                cookie.Value = value;
                cookie.Expires = DateTime.Now.AddMinutes(expires);
                context.Response.Cookies.Add(cookie);
            }

            public static void SetCookie(HttpContext context, string name, string key, string value, double expires = 60*24)
            {
                HttpCookie cookie = context.Request.Cookies[name];
                if (cookie == null)
                {
                    cookie = new HttpCookie(name);
                }
                //cookie.Values.Add(key, value);
                cookie[key] = value;
                cookie.Expires = DateTime.Now.AddMinutes(expires);
                context.Response.Cookies.Add(cookie);
            }
        }

        /// <summary>
        /// request session cookie取出来的string都不是null
        /// </summary>
        public class Request
        {
            #region 获取get，post数据
            /// <summary>
            /// Get
            /// </summary>
            /// <param name="Request"></param>
            /// <param name="key"></param>
            /// <returns></returns>
            public static string GetGetString(HttpRequest Request, string key, string deft = "")
            {
                string prm = ConvertHelper.getString(Request.QueryString[key]);
                if (!ValidateHelper.IsPlumpString(prm))
                {
                    return deft;
                }
                return prm;
            }
            /// <summary>
            /// Post
            /// </summary>
            /// <param name="Request"></param>
            /// <param name="key"></param>
            /// <returns></returns>
            public static string GetPostString(HttpRequest Request, string key, string deft = "")
            {
                string prm = ConvertHelper.getString(Request.Form[key]);
                if (!ValidateHelper.IsPlumpString(prm))
                {
                    return deft;
                }
                return prm;
            }
            /// <summary>
            /// Request
            /// </summary>
            /// <param name="Request"></param>
            /// <param name="key"></param>
            /// <returns></returns>
            public static string GetRequestString(HttpRequest Request, string key, string deft = "")
            {
                string prm = ConvertHelper.getString(Request.Params[key]);
                if (!ValidateHelper.IsPlumpString(prm))
                {
                    return deft;
                }
                return prm;
            }
            /// <summary>
            /// HttpPostFile
            /// </summary>
            /// <param name="Request"></param>
            /// <param name="key"></param>
            /// <returns></returns>
            public static HttpPostedFile GetPostFile(HttpRequest Request, string key)
            {
                return Request.Files[key];
            }
            public static List<HttpPostedFile> GetPostFileList(HttpRequest Request)
            {
                List<HttpPostedFile> list = new List<HttpPostedFile>();
                for (int i = 0; i < Request.Files.Count; ++i)
                {
                    list.Add(Request.Files[i]);
                }
                return list;
            }
            #endregion
            /// <summary>
            /// 
            /// </summary>
            /// <param name="request"></param>
            /// <returns></returns>
            public static string GetBaseUrl(HttpRequest request)
            {
                return request == null ? string.Empty :
                    request.Url.Scheme + "://" + request.Url.Authority + request.ApplicationPath;
            }
            public static string GetCurrentUrl(HttpRequest request)
            {
                //string url = GetBaseUrl(request)+request.Url.Scheme + request.Path +"/"+ request.QueryString;
                //Debug.Write(url);
                return request.Url.ToString();
            }
            /// <summary>
            /// 
            /// </summary>
            /// <param name="Request"></param>
            /// <param name="path"></param>
            /// <returns></returns>
            public static string MapPath(HttpRequest Request, string path)
            {
                return Request == null ? string.Empty : ConvertHelper.getString(Request.MapPath(path));
            }
            /// <summary>
            /// 
            /// </summary>
            /// <param name="Request"></param>
            /// <returns></returns>
            public static bool IsPost(HttpRequest Request)
            {
                return Request != null && Request.HttpMethod == "POST";
            }
            public static bool IsGet(HttpRequest Request)
            {
                return Request != null && Request.HttpMethod == "GET";
            }
            public static bool IsAjax(HttpRequest Request)
            {
                return Request != null && Request.Headers["X-Requested-With"] == "XMLHttpRequest";
            }
            public static bool IsPostAjax(HttpRequest Request)
            {
                return IsPost(Request) && IsAjax(Request);
            }
            public static bool IsGetAjax(HttpRequest Request)
            {
                return IsGet(Request) && IsAjax(Request);
            }

            /// <summary>
            /// 获得上次请求的url
            /// </summary>
            /// <returns></returns>
            public static string GetUrlReferrer(HttpRequest Request)
            {
                //string re=HttpContext.Current.Request.Headers["referrer"];
                Uri uri = Request.UrlReferrer;
                return ConvertHelper.getString(uri);
            }

            /// <summary>
            /// 获得请求的原始url
            /// </summary>
            /// <returns></returns>
            public static string GetRawUrl(HttpRequest Request)
            {
                return ConvertHelper.getString(Request.RawUrl);
            }

            public static string GetUserIP(HttpRequest Request)
            {
                return ConvertHelper.getString(Request.UserHostAddress);
                //string ip = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                //if (string.IsNullOrEmpty(ip))
                //{
                //    ip = Request.ServerVariables["REMOTE_ADDR"];
                //}

                //return ip;
            }
            public static string[] GetUserLanguages(HttpRequest Request)
            {
                return Request.UserLanguages;
            }
            public static string GetUserAgent(HttpRequest Request)
            {
                return ConvertHelper.getString(Request.UserAgent);
            }
            public static string GetUserHostName(HttpRequest Request)
            {
                return ConvertHelper.getString(Request.UserHostName);
            }
            public static string GetUserHost(HttpRequest Request)
            {
                return ConvertHelper.getString(Request.Url.Host);
            }

            /// <summary>  
            /// 创建POST方式的HTTP请求  
            /// </summary>  
            /// <param name="url">请求的URL</param>  
            /// <param name="parameters">随同请求POST的参数名称及参数值字典</param>  
            /// <param name="base64">Authorization</param>  
            /// <param name="userAgent">请求的客户端浏览器信息，可以为空</param>  
            /// <param name="requestEncoding">发送HTTP请求时所用的编码</param>  
            /// <param name="cookies">随同HTTP请求发送的Cookie信息，如果不需要身份验证可以为空</param>  
            /// <returns></returns>  
            public static string HttpPostRequestForWechat(string authorization,string serial, string url, string postData)
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "POST";
                request.ContentType = "application/json";
                request.Headers["Authorization"] = authorization;
                request.Accept = "application/json";
                request.Headers["Wechatpay-Serial"] = serial;
                request.UserAgent = "Mozilla/5.0 (Linux; U; Android 4.1.2; zh-cn; GT-I9300 Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 MicroMessenger/5.2.380";
                //request.TransferEncoding = "chunked";

                byte[] tyteStr = Encoding.UTF8.GetBytes(postData);
                //request.ContentLength = tyteStr.Length;
                StreamWriter writer = new StreamWriter(request.GetRequestStream());
                writer.Write(postData);
                writer.Flush();
                try
                {
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    Stream myResponseStream = response.GetResponseStream();
                    StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
                    string retString = myStreamReader.ReadToEnd();
                    myStreamReader.Close();
                    myResponseStream.Close();

                    return retString;
                }
                catch (WebException ex)
                {
                    HttpWebResponse errorResponse = (HttpWebResponse)ex.Response;
                    using (Stream responseStream = errorResponse.GetResponseStream())
                    {
                        // 读取错误信息等
                        StreamReader myStreamReader = new StreamReader(responseStream, Encoding.UTF8);
                        string retString = myStreamReader.ReadToEnd();
                        return retString;
                    }
                }
                catch (Exception ex)
                {
                    return ex.Message;
                }
            }
        }

        public class Response
        {
            /// <summary>
            /// 设置不缓存
            /// </summary>
            /// <param name="response"></param>
            public static void setResponseNoCache(HttpResponse response)
            {
                response.Buffer = false;
                response.ExpiresAbsolute = System.DateTime.Now.AddMilliseconds(0);
                response.Expires = 0;
                response.CacheControl = "no-cache";
                response.AppendHeader("Pragma", "No-Cache");
            }
        }

        public class Session
        {
            public static string PopSessionString(HttpSessionState session, string key)
            {
                return ConvertHelper.getString(PopSession<object>(session, key));
            }

            public static T PopSession<T>(HttpSessionState session, string key)
            {
                T value = GetSession<T>(session, key);
                RemoveSession(session, key);
                return value;
            }

            public static string GetSessionString(HttpSessionState session, string key)
            {
                return ConvertHelper.getString(GetSession<object>(session, key));
            }

            public static T GetSession<T>(HttpSessionState session, string key)
            {
                try
                {
                    if (session == null) { return default(T); }
                    object obj = session[key];
                    if (ValidateHelper.Is<T>(obj))
                    {
                        return (T)obj;
                    }
                }
                catch (Exception e)
                {
                    Console.Write(e.Message);
                }
                return default(T);
            }

            public static bool SetSession(HttpSessionState session, string key, object value)
            {
                try
                {
                    if (session == null) { return false; }
                    session[key] = value;
                    return true;
                }
                catch (Exception e)
                {
                    return false;
                }
            }

            public static bool RemoveSession(HttpSessionState session, params string[] keys)
            {
                try
                {
                    if (session == null || keys == null) { return false; }
                    for (int i = 0; i < keys.Length; ++i)
                    {
                        if (keys[i] == null) { continue; }
                        session.Remove(keys[i]);
                    }
                    return true;
                }
                catch (Exception e)
                {
                    return false;
                }
            }
        }

        public class Client
        {
            #region 客户端信息

            /// <summary>
            /// 获得请求的ip
            /// </summary>
            /// <returns></returns>
            public static string GetIP()
            {
                string ip = string.Empty;
                if (HttpContext.Current.Request.ServerVariables["HTTP_VIA"] != null)
                    ip = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();
                else
                    ip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"].ToString();

                if (!ValidateHelper.IsPlumpString(ip) || !ValidateHelper.IsIP(ip))
                    ip = "127.0.0.1";
                return ip;
            }

            /// <summary>
            /// 获得请求的浏览器类型
            /// </summary>
            /// <returns></returns>
            public static string GetBrowserType()
            {
                string type = HttpContext.Current.Request.Browser.Type;
                if (string.IsNullOrEmpty(type) || type == "unknown")
                    return "未知";

                return type.ToLower();
            }

            /// <summary>
            /// 获得请求的浏览器名称
            /// </summary>
            /// <returns></returns>
            public static string GetBrowserName()
            {
                string name = HttpContext.Current.Request.Browser.Browser;
                if (string.IsNullOrEmpty(name) || name == "unknown")
                    return "未知";

                return name.ToLower();
            }

            /// <summary>
            /// 获得请求的浏览器版本
            /// </summary>
            /// <returns></returns>
            public static string GetBrowserVersion()
            {
                string version = HttpContext.Current.Request.Browser.Version;
                if (string.IsNullOrEmpty(version) || version == "unknown")
                    return "未知";

                return version;
            }

            /// <summary>
            /// 获得请求客户端的操作系统类型
            /// </summary>
            /// <returns></returns>
            public static string GetOSType()
            {
                string type = "未知";
                string userAgent = HttpContext.Current.Request.UserAgent;

                if (userAgent.Contains("NT 6.1"))
                {
                    type = "Windows 7";
                }
                else if (userAgent.Contains("NT 5.1"))
                {
                    type = "Windows XP";
                }
                else if (userAgent.Contains("NT 6.2"))
                {
                    type = "Windows 8";
                }
                else if (userAgent.Contains("android"))
                {
                    type = "Android";
                }
                else if (userAgent.Contains("iphone"))
                {
                    type = "IPhone";
                }
                else if (userAgent.Contains("Mac"))
                {
                    type = "Mac";
                }
                else if (userAgent.Contains("NT 6.0"))
                {
                    type = "Windows Vista";
                }
                else if (userAgent.Contains("NT 5.2"))
                {
                    type = "Windows 2003";
                }
                else if (userAgent.Contains("NT 5.0"))
                {
                    type = "Windows 2000";
                }
                else if (userAgent.Contains("98"))
                {
                    type = "Windows 98";
                }
                else if (userAgent.Contains("95"))
                {
                    type = "Windows 95";
                }
                else if (userAgent.Contains("Me"))
                {
                    type = "Windows Me";
                }
                else if (userAgent.Contains("NT 4"))
                {
                    type = "Windows NT4";
                }
                else if (userAgent.Contains("Unix"))
                {
                    type = "UNIX";
                }
                else if (userAgent.Contains("Linux"))
                {
                    type = "Linux";
                }
                else if (userAgent.Contains("SunOS"))
                {
                    type = "SunOS";
                }

                return type;
            }

            /// <summary>
            /// 获得请求客户端的操作系统名称
            /// </summary>
            /// <returns></returns>
            public static string GetOSName()
            {
                string name = HttpContext.Current.Request.Browser.Platform;
                if (string.IsNullOrEmpty(name))
                    return "未知";

                return name;
            }

            /// <summary>
            /// 判断是否是浏览器请求
            /// </summary>
            /// <returns></returns>
            public static bool IsBrowser()
            {
                string name = GetBrowserName();
                foreach (string item in XQ.Framework.net.HttpClient.BROWSER_LIST)
                {
                    if (name.Contains(item))
                        return true;
                }
                return false;
            }

            /// <summary>
            /// 是否是移动设备请求
            /// </summary>
            /// <returns></returns>
            public static bool IsMobile()
            {
                if (HttpContext.Current.Request.Browser.IsMobileDevice)
                    return true;

                bool isTablet = false;
                if (bool.TryParse(HttpContext.Current.Request.Browser["IsTablet"], out isTablet) && isTablet)
                    return true;

                return false;
            }

            /// <summary>
            /// 判断是否是搜索引擎爬虫请求
            /// </summary>
            /// <returns></returns>
            public static bool IsCrawler(HttpRequest Request)
            {
                bool result = Request.Browser.Crawler;
                if (!result)
                {
                    string referrer = HttpHelper.Request.GetUrlReferrer(Request);
                    if (referrer.Length > 0)
                    {
                        foreach (string item in XQ.Framework.net.HttpClient.SEARCH_ENGINE_LIST)
                        {
                            if (referrer.Contains(item))
                            {
                                return true;
                            }
                        }
                    }
                }
                return result;
            }

            #endregion
        }

        public class Server
        {
            public static string GetMapPath(HttpContext context, string path)
            {
                return context.Server.MapPath(path);
            }

            public static string HtmlEncode(HttpContext context, string str)
            {
                return context.Server.HtmlEncode(str);
            }
            public static string HtmlDecode(HttpContext context, string str)
            {
                return context.Server.HtmlDecode(str);
            }
            /// <summary>
            /// 获得当前应用程序的信任级别
            /// </summary>
            /// <returns></returns>
            public static AspNetHostingPermissionLevel GetTrustLevel()
            {
                AspNetHostingPermissionLevel trustLevel = AspNetHostingPermissionLevel.None;
                //权限列表
                AspNetHostingPermissionLevel[] levelList = new AspNetHostingPermissionLevel[] {
                                                                                            AspNetHostingPermissionLevel.Unrestricted,
                                                                                            AspNetHostingPermissionLevel.High,
                                                                                            AspNetHostingPermissionLevel.Medium,
                                                                                            AspNetHostingPermissionLevel.Low,
                                                                                            AspNetHostingPermissionLevel.Minimal 
                                                                                            };

                foreach (AspNetHostingPermissionLevel level in levelList)
                {
                    try
                    {
                        //通过执行Demand方法检测是否抛出SecurityException异常来设置当前应用程序的信任级别
                        new AspNetHostingPermission(level).Demand();
                        trustLevel = level;
                        break;
                    }
                    catch (SecurityException ex)
                    {
                        continue;
                    }
                }
                return trustLevel;
            }


            /// <summary>
            /// 重启应用程序
            /// </summary>
            public static void RestartAppDomain(HttpContext context)
            {
                if (GetTrustLevel() > AspNetHostingPermissionLevel.Medium)//如果当前信任级别大于Medium，则通过卸载应用程序域的方式重启
                {
                    HttpRuntime.UnloadAppDomain();
                }
                else//通过修改web.config方式重启应用程序
                {
                    try
                    {
                        File.SetLastWriteTime(HttpHelper.Server.GetMapPath(context, "~/Web.config"), DateTime.Now);
                    }
                    catch { }
                }
            }

        }

        public class Application
        { }

        public class Url
        {
            public static string UrlEncode(string s)
            {
                return HttpUtility.UrlEncode(ConvertHelper.getString(s));
            }
            public static string UrlDecode(string s)
            {
                return HttpUtility.UrlDecode(ConvertHelper.getString(s));
            }
        }
    }
}